﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using PatientInformationExtract.Components;
using System.Xml;
using PatientInformationExtract.Dictionary.Views;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using PanGu;
using System.Text.RegularExpressions;

namespace PatientInformationExtract.Dictionary.ViewModels
{
    public class TranslationLearningDictionaryManageViewModel : WindowViewModelBase
    {
        private const string CUnknownSegmentsStatus = "Unknown segments count: ";
        private const string CModifiedWordsStatus = "Modified words count: ";
        private const string CUnmodifiedWordsStatus = "Unmodified words count: ";
        private const string CTotalStatus = "Dictionary words count: ";
        private List<string> _unknownSegments;
        private List<string> _modifiedWords;
        private List<string> _unmodifiedWords;

        private string _dictionaryFilePath;
        public string DictionaryFilePath { get { return this._dictionaryFilePath; } }

        private XmlDocument _xmlDoc;
        public XmlDocument XmlDoc { get { return this._xmlDoc; } }

        private string _unknownSegmentsStatus;
        public string UnknownSegmentsStatus
        {
            get { return this._unknownSegmentsStatus; }
            set
            {
                if (this._unknownSegmentsStatus != value)
                {
                    this._unknownSegmentsStatus = value;
                    base.NotifyPropertyChanged("UnknownSegmentsStatus");
                }
            }
        }

        public string TotalStatus { get { return CTotalStatus + (this._modifiedWords.Count + this._unmodifiedWords.Count).ToString(); } }

        private string _modifiedWordsStatus;
        public string ModifiedWordsStatus
        {
            get { return this._modifiedWordsStatus; }
            set
            {
                if (this._modifiedWordsStatus != value)
                {
                    this._modifiedWordsStatus = value;
                    base.NotifyPropertyChanged("TotalStatus");
                    base.NotifyPropertyChanged("ModifiedWordsStatus");
                }
            }
        }

        private string _unmodifiedWordsStatus;
        public string UnmodifiedWordsStatus
        {
            get { return this._unmodifiedWordsStatus; }
            set
            {
                if (this._unmodifiedWordsStatus != value)
                {
                    this._unmodifiedWordsStatus = value;
                    base.NotifyPropertyChanged("TotalStatus");
                    base.NotifyPropertyChanged("UnmodifiedWordsStatus");
                }
            }
        }

        private ICommand _saveAndRefreshCommand;
        public ICommand SaveAndRefreshCommand { get { return this._saveAndRefreshCommand; } }

        public delegate void TranslationLearningDictionaryManageClosedHandler();
        public event TranslationLearningDictionaryManageClosedHandler TranslationLearningDictionaryManageClosedEvent;

        public TranslationLearningDictionaryManageViewModel(WindowViewModelBase parent, string dictionaryFilePath)
        {
            this._xmlDoc = new XmlDocument();
            this._dictionaryFilePath = dictionaryFilePath;
            this._xmlDoc.Load(this._dictionaryFilePath);
            this._unknownSegments = new List<string>();
            this._modifiedWords = new List<string>();
            this._unmodifiedWords = new List<string>();

            this._saveAndRefreshCommand = new Command(new Action<object>(this.SaveAndRefresh));

            LoadDictionary();

            base._parent = parent;
            WindowInitialize();
        }

        protected override void WindowInitialize()
        {
            base.WindowInitialize();
            base._window = new TranslationLearningDictionaryManageWindow(this);
            base._window.Closing += new System.ComponentModel.CancelEventHandler(window_Closing);
            base._window.DataContext = this;
        }

        private void window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
        {
            XmlDocument xml = new XmlDocument();
            xml.Load(this._dictionaryFilePath);
            if (!xml.OuterXml.Equals(_xmlDoc.OuterXml))
            {
                MessageBoxResult result = MessageBox.Show("Translation learning dictionary has modified, do you want to save the change?", "Save", MessageBoxButton.YesNoCancel, MessageBoxImage.Warning);
                if (result == MessageBoxResult.Yes)
                {
                    this._xmlDoc.Save(this._dictionaryFilePath);
                    if (this.TranslationLearningDictionaryManageClosedEvent != null)
                    {
                        this.TranslationLearningDictionaryManageClosedEvent();
                    }
                }
                else if (result == MessageBoxResult.Cancel)
                {
                    e.Cancel = true;
                }
            }
        }

        private void LoadDictionary()
        {
            this._modifiedWords.Clear();
            this._unmodifiedWords.Clear();
            this._unknownSegments.Clear();
            XmlNodeList translationNodes = this._xmlDoc.SelectNodes("/TranslationLearningDictionary/Translation");
            foreach (XmlNode node in translationNodes)
            {
                string chinese = node.Attributes["Chinese"].Value;
                if (node.Attributes["ManuallyModified"].Value.Equals("True"))
                {
                    this._modifiedWords.Add(chinese);
                }
                else
                {
                    this._unmodifiedWords.Add(chinese);
                }

                foreach (string segment in node.Attributes["UnknownSegments"].Value.Split(new char[] { ',' }))
                {
                    if (!this._unknownSegments.Contains(segment))
                    {
                        this._unknownSegments.Add(segment);
                    }
                }
            }
            this.UnknownSegmentsStatus = CUnknownSegmentsStatus + this._unknownSegments.Count.ToString();
            this.UnmodifiedWordsStatus = CUnmodifiedWordsStatus + this._unmodifiedWords.Count.ToString();
            this.ModifiedWordsStatus = CModifiedWordsStatus + this._modifiedWords.Count.ToString();
            NotifyPropertyChanged("XmlDoc");
        }

        private void SaveAndRefresh(object o)
        {
            (this.Parent as DictionaryManageViewModel).Save();
            Segment segment = new Segment();
            XmlNode rootNode = this._xmlDoc.SelectSingleNode("/TranslationLearningDictionary");
            XmlNodeList translationNodes = this._xmlDoc.SelectNodes("/TranslationLearningDictionary/Translation");
            foreach (XmlNode node in translationNodes)
            {
                string chinese = node.Attributes["Chinese"].Value;
                ICollection<WordInfo> result = segment.DoSegment(chinese, false);
                List<string> unknownSegments = new List<string>();
                bool canTranslatedToEnglish = true;
                foreach (WordInfo word in result)
                {
                    if (word.Pos.Equals(POS.POS_UNK))
                    {
                        if (!Regex.IsMatch(word.Word, "^[0-9a-zA-Z ]+$"))
                        {
                            canTranslatedToEnglish = false;
                            unknownSegments.Add(word.Word);
                        }
                    }
                    else if (word.Pos.Equals(POS.POS_SYMBOL))
                    {
                    }
                    else
                    {
                        if (String.IsNullOrEmpty(word.English))
                        {
                            canTranslatedToEnglish = false;
                            unknownSegments.Add(word.Word);
                        }
                    }
                }
                if (canTranslatedToEnglish)
                {
                    rootNode.RemoveChild(node);
                }
                else
                {
                    node.Attributes["UnknownSegments"].Value = String.Join(",", unknownSegments);
                }
            }
            this._xmlDoc.Save(this._dictionaryFilePath);
            LoadDictionary();
        }

        public bool DeleteRecordByChinese(string chinese)
        {
            XmlNode nodeToDelete=this._xmlDoc.SelectSingleNode(@"/TranslationLearningDictionary/Translation[@Chinese='"+chinese+@"']");
            if(nodeToDelete==null)
            {
                return false;
            }
            else
            {
                this._xmlDoc.SelectSingleNode("/TranslationLearningDictionary").RemoveChild(nodeToDelete);
                NotifyPropertyChanged("XmlDoc");
                return true;
            }          
        }
    }
}
